<template>
  <a-select :value="checkedStr" :placeholder="t('pleaseSelect')">
    <template #dropdownRender>
      <div class="drop-down-menu" @mousedown="e => e.preventDefault()">
        <a-row>
          <a-checkbox
            class="dropdown-checkbox"
            :indeterminate="state.indeterminate"
            :checked="state.checkAll"
            @change="handleCheckAllChange"
          >
            {{ t('all') }}
          </a-checkbox>
        </a-row>
        <a-checkbox-group v-model:value="state.checkedList" @change="handleChange">
          <a-row v-for="item in state.dataList" :key="item.value">
            <a-checkbox class="dropdown-checkbox" :value="item.value">
              {{ item.label }}
            </a-checkbox>
          </a-row>
        </a-checkbox-group>
      </div>
    </template>
  </a-select>
</template>

<script lang="ts">
  import { computed, defineComponent, onMounted, reactive, watch } from 'vue'
  import { useI18n } from 'vue-i18n'
  import { isArray } from '@/utils/is'

  type SourceColumnData = {
    label?: string
    value?: string
    name?: string
    id?: string
    children?: SourceColumnData[]
  }
  type ColumnData = {
    label: string
    value: string
  }
  interface ColumnDataSelectState {
    checkedList: string[]
    indeterminate: boolean
    checkAll: boolean
    dataList: ColumnData[]
  }
  export default defineComponent({
    name: 'ColumnDataSelect',
    props: {
      // 列信息
      columnInfo: {
        type: Object as PropType<FiledListType>,
        default: () => ({})
      },
      value: {
        type: Array as PropType<string[]>,
        default: () => []
      }
    },
    emits: ['update:value'],
    setup(props, { emit }) {
      const { t } = useI18n()

      const state = reactive<ColumnDataSelectState>({
        checkedList: [],
        indeterminate: false,
        checkAll: false,
        dataList: []
      })

      const checkedStr = computed(() => {
        if (state.checkedList) {
          return state.checkedList.map(item => fieldsMap.value[item]).join(',')
        }
        return ''
      })

      /**
       * 用于value转换为中文提示的map
       * 方便checkedStr计算
       */
      const fieldsMap = computed(() => {
        const data = {}
        state.dataList.forEach(item => {
          data[item.value] = item.label
        })
        return data
      })

      // 点击勾选配置选项
      const handleChange = list => {
        state.indeterminate = Boolean(list.length) && list.length < state.dataList.length
        state.checkAll = Boolean(state.dataList.length) && list.length === state.dataList.length
        emit('update:value', state.checkedList)
      }

      watch(
        () => props.value,
        () => {
          if (state.checkedList !== props.value) {
            state.checkedList = props.value
            handleChange(props.value)
          }
        },
        {
          immediate: true
        }
      )

      onMounted(() => {
        handleChange(props.value)
        if (!currentBlock) {
          return
        }
        state.dataList = getDataList(currentBlock.dynamicOptions)
      })
      // 转换配置的选项数据统一为label/value的格式
      const getDataList = (selectOptions: Array<SourceColumnData> = []): Array<ColumnData> => {
        if (!isArray(selectOptions)) {
          return []
        }
        let result: Array<ColumnData> = []
        selectOptions.forEach(item => {
          result.push({
            label: item.label ?? item.name ?? '',
            value: item.id ?? item.value ?? ''
          })
          if (item.children) {
            const { children } = item
            result = result.concat(getDataList(children))
          }
        })
        return result
      }
      // 勾选全部
      const handleCheckAllChange = event => {
        state.checkedList = event.target.checked ? state.dataList.map(item => item.value) : []
        state.indeterminate = false
        state.checkAll = event.target.checked
        emit('update:value', state.checkedList)
      }

      return {
        t,
        checkedStr,
        state,
        handleChange,
        handleCheckAllChange
      }
    }
  })
</script>

<style lang="less" scoped>
  .dropdown-checkbox {
    margin: 5px 10px;
  }

  .drop-down-menu {
    max-height: 300px;
    overflow: auto;
  }
</style>

<i18n>
zh-CN:
  pleaseSelect: '请选择'
</i18n>
